/**
 * Coin Slider - Unique jQuery Image Slider
 * @version: 1.0 - (2010/04/04)
 * @requires jQuery v1.2.2 or later
 * @author Ivan Lazarevic
 * Examples and documentation at: http://workshop.rs/projects/coin-slider/

 * Licensed under MIT licence:
 *   http://www.opensource.org/licenses/mit-license.php
**/

(function ($) {

        var        params                = [],
                order                = [],
                images                = [],
                links                = [],
                linksTarget        = [],
                titles                = [],
                interval        = [],
                imagePos        = [],
                appInterval        = [],
                squarePos        = [],
                reverse                = [],
                uniqueIDPrefix        = "coinsliderUniqueID",
                uniqueIDCounter        = 0;

        $.fn.coinslider = $.fn.CoinSlider = function (options) {

                // squares positions
                var setFields = function (el) {

                        var        tWidth        = parseInt(params[el.id].width / params[el.id].spw),
                                sWidth        = tWidth,
                                tHeight        = parseInt(params[el.id].height / params[el.id].sph),
                                sHeight        = tHeight,
                                counter        = 0,
                                sLeft        = 0,
                                sTop        = 0,
                                i,
                                j,
                                tgapx        = params[el.id].width - params[el.id].spw * sWidth,
                                gapx        = tgapx,
                                tgapy        = params[el.id].height - params[el.id].sph * sHeight,
                                gapy        = tgapy;

                        for (i = 1; i <= params[el.id].sph; i++) {
                                gapx = tgapx;

                                if (gapy > 0) {
                                        gapy--;
                                        sHeight = tHeight + 1;
                                } else {
                                        sHeight = tHeight;
                                }

                                for (j = 1; j <= params[el.id].spw; j++) {

                                        if (gapx > 0) {
                                                gapx--;
                                                sWidth = tWidth + 1;
                                        } else {
                                                sWidth = tWidth;
                                        }

                                        order[el.id][counter] = i + "" + j;
                                        counter++;

                                        if (params[el.id].links) {
                                                $('#' + el.id).append("<a href='" + links[el.id][0] + "' class='cs-" + el.id + "' id='cs-" + el.id + i + j + "' style='width:" + sWidth + "px; height:" + sHeight + "px; float: left; position: absolute;'></a>");
                                        } else {
                                                $('#' + el.id).append("<div class='cs-" + el.id + "' id='cs-" + el.id + i + j + "' style='width:" + sWidth + "px; height:" + sHeight + "px; float: left; position: absolute;'></div>");
                                        }

                                        // positioning squares
                                        $("#cs-" + el.id + i + j).css({
                                                'background-position': -sLeft + 'px ' + (-sTop + 'px'),
                                                'left' : sLeft,
                                                'top': sTop
                                        });

                                        sLeft += sWidth;
                                }

                                sTop += sHeight;
                                sLeft = 0;

                        }

                        if (!params[el.id].navigationPrevNextAlwaysShown) {

                                $('.cs-' + el.id).mouseover(function(){
                                        $('#cs-navigation-' + el.id).show();
                                });

                                $('.cs-' + el.id).mouseout(function(){
                                        $('#cs-navigation-' + el.id).hide();
                                });

                                $('#cs-title-' + el.id).mouseover(function(){
                                        $('#cs-navigation-' + el.id).show();
                                });

                                $('#cs-title-' + el.id).mouseout(function(){
                                        $('#cs-navigation-' + el.id).hide();
                                });
                        }

                        if (params[el.id].hoverPause) {
                                $('.cs-' + el.id).mouseover(function(){
                                        params[el.id].pause = true;
                                });

                                $('.cs-' + el.id).mouseout(function(){
                                        params[el.id].pause = false;
                                });

                                $('#cs-title-' + el.id).mouseover(function(){
                                        params[el.id].pause = true;
                                });

                                $('#cs-title-' + el.id).mouseout(function(){
                                        params[el.id].pause = false;
                                });
                        }

                };

                var transitionCall = function (el) {

                        clearInterval(interval[el.id]);
                        var delay = params[el.id].delay + params[el.id].spw * params[el.id].sph * params[el.id].sDelay;
                        interval[el.id] = setInterval(function() { transition(el);  }, delay);

                };

                // transitions
                var transition = function (el, direction) {

                        if(params[el.id].pause === true){
                                return;
                        }

                        effect(el);

                        squarePos[el.id] = 0;
                        appInterval[el.id] = setInterval(function() { appereance(el,order[el.id][squarePos[el.id]]);  },params[el.id].sDelay);

                        $(el).css({ 'background-image': 'url(' + images[el.id][imagePos[el.id]] + ')' });

                        if (typeof(direction) == "undefined") {
                                imagePos[el.id]++;
                        } else {
                                if (direction == 'prev') {
                                        imagePos[el.id]--;
                                } else {
                                        imagePos[el.id] = direction;
                                }
                        }

                        if (imagePos[el.id] == images[el.id].length) {
                                imagePos[el.id] = 0;
                        }

                        if (imagePos[el.id] == -1) {
                                imagePos[el.id] = images[el.id].length-1;
                        }

                        $('.cs-button-' + el.id).removeClass('cs-active');
                        $('#cs-button-' + el.id + "-" + (imagePos[el.id] + 1)).addClass('cs-active');

                        if (titles[el.id][imagePos[el.id]]) {
                                $('#cs-title-' + el.id).css({ 'opacity' : 0 }).animate({ 'opacity' : params[el.id].opacity }, params[el.id].titleSpeed);
                                $('#cs-title-' + el.id).html(titles[el.id][imagePos[el.id]]);
                        } else {
                                $('#cs-title-' + el.id).css('opacity',0);
                        }

                };

                var appereance = function (el, sid) {

                        $('.cs-' + el.id).attr('href',links[el.id][imagePos[el.id]]).attr('target',linksTarget[el.id][imagePos[el.id]]);

                        if (squarePos[el.id] == params[el.id].spw * params[el.id].sph) {
                                clearInterval(appInterval[el.id]);
                                return;
                        }

                        $('#cs-' + el.id + sid).css({ opacity: 0, 'background-image': 'url(' + images[el.id][imagePos[el.id]] + ')' });
                        $('#cs-' + el.id + sid).animate({ opacity: 1 }, 300);
                        squarePos[el.id]++;

                };

                // navigation
                var setNavigation = function (el) {
                        // create prev and next
                        if (params[el.id].showNavigationPrevNext) {
                                $(el).append("<div id='cs-navigation-" + el.id + "'></div>");

                                if (!params[el.id].navigationPrevNextAlwaysShown) {
                                        $('#cs-navigation-' + el.id).hide();
                                }

                                $('#cs-navigation-' + el.id).append("<a href='#' id='cs-prev-" + el.id + "' class='cs-prev'>"+params[el.id].prevText+"</a>");
                                $('#cs-navigation-' + el.id).append("<a href='#' id='cs-next-" + el.id + "' class='cs-next'>"+params[el.id].nextText+"</a>");
                                $('#cs-prev-' + el.id).css({
                                        'position'                : 'absolute',
                                        'top'                        : params[el.id].height / 2 - 15,
                                        'left'                        : 0,
                                        'z-index'                : 1001,
                                        'line-height'        : '30px',
                                        'opacity'                : params[el.id].opacity
                                }).click( function(e){
                                        e.preventDefault();
                                        transition(el,'prev');
                                        transitionCall(el);
                                }).mouseover( function(){ $('#cs-navigation-' + el.id).show(); });

                                $('#cs-next-' + el.id).css({
                                        'position'                : 'absolute',
                                        'top'                        : params[el.id].height / 2 - 15,
                                        'right'                        : 0,
                                        'z-index'                : 1001,
                                        'line-height'        : '30px',
                                        'opacity'                : params[el.id].opacity
                                }).click( function(e){
                                        e.preventDefault();
                                        transition(el);
                                        transitionCall(el);
                                }).mouseover( function(){ $('#cs-navigation-' + el.id).show(); });

                                $('#cs-navigation-' + el.id + ' a').mouseout(function(){
                                        if (!params[el.id].navigationPrevNextAlwaysShown)
                                                $('#cs-navigation-' + el.id).hide();

                                        params[el.id].pause = false;
                                });
                        }

                        // image buttons
                        if (params[el.id].showNavigationButtons) {
                                $("<div id='cs-buttons-" + el.id + "' class='cs-buttons'></div>").appendTo($('#coin-slider-' + el.id));

                                var k;
                                for (k = 1; k < images[el.id].length + 1; k++){
                                        $('#cs-buttons-' + el.id).append("<a href='#' class='cs-button-" + el.id + "' id='cs-button-" + el.id + "-" + k + "'>" + k + "</a>");
                                }

                                $.each($('.cs-button-' + el.id), function(i,item){
                                        $(item).click( function(e){
                                                $('.cs-button-' + el.id).removeClass('cs-active');
                                                $(this).addClass('cs-active');
                                                e.preventDefault();
                                                transition(el,i);
                                                transitionCall(el);
                                        });
                                });

                                $("#cs-buttons-" + el.id).css({
                                        'left'                        : '50%',
                                        'margin-left'        : -images[el.id].length * 15 / 2 - 5,
                                        'position'                : 'relative'
                                });
                        }

                };

                // effects
                var effect = function (el) {
                        var effA = ['random','swirl','rain','straight'],
                                i,
                                j,
                                counter,
                                eff;

                        if (params[el.id].effect === '') {
                                eff = effA[Math.floor(Math.random() * (effA.length))];
                        } else {
                                eff = params[el.id].effect;
                        }

                        order[el.id] = [];

                        if (eff == 'random') {
                                counter = 0;
                                        for (i = 1; i <= params[el.id].sph; i++) {
                                                for (j = 1; j <= params[el.id].spw; j++) {
                                                        order[el.id][counter] = i + "" + j;
                                                        counter++;
                                                }
                                        }
                                randomEffect(order[el.id]);
                        }

                        if (eff == 'rain') {
                                rain(el);
                        }

                        if (eff == 'swirl') {
                                swirl(el);
                        }

                        if (eff == 'straight') {
                                straight(el);
                        }

                        reverse[el.id] *= -1;

                        if (reverse[el.id] > 0) {
                                order[el.id].reverse();
                        }

                };

                // shuffle array function
                var randomEffect = function (arr) {

                        var i = arr.length,
                                j,
                                tempi,
                                tempj;

                        if ( i === 0 ) {
                                return false;
                        }

                        while ( --i ) {
                                j = Math.floor( Math.random() * ( i + 1 ) );
                                tempi = arr[i];
                                tempj = arr[j];
                                arr[i] = tempj;
                                arr[j] = tempi;
                        }
                };

                //swirl effect by milos popovic
                var swirl = function (el) {

                        var n = params[el.id].sph,
                                m = params[el.id].spw,
                                x = 1,
                                y = 1,
                                going = 0,
                                num = 0,
                                c = 0,
                                check,
                                dowhile = true,
                                i;

                        while (dowhile) {

                                num = (going === 0 || going === 2) ? m : n;

                                for (i = 1; i <= num; i++){

                                        order[el.id][c] = x + "" + y;
                                        c++;

                                        if (i != num) {
                                                switch(going){
                                                        case 0 : y++; break;
                                                        case 1 : x++; break;
                                                        case 2 : y--; break;
                                                        case 3 : x--; break;

                                                }
                                        }
                                }

                                going = (going + 1) % 4;

                                switch (going) {
                                        case 0 : m--; y++; break;
                                        case 1 : n--; x++; break;
                                        case 2 : m--; y--; break;
                                        case 3 : n--; x--; break;
                                }

                                check = max(n,m) - min(n,m);
                                if (m <= check && n <= check) {
                                        dowhile = false;
                                }

                        }
                };

                // rain effect
                var rain = function (el) {

                        var n = params[el.id].sph,
                                m = params[el.id].spw,
                                c = 0,
                                to = 1,
                                to2 = 1,
                                from = 1,
                                dowhile = true;

                        while (dowhile) {

                                for (i = from; i <= to; i++) {
                                        order[el.id][c] = i + '' + parseInt(to2 - i + 1);
                                        c++;
                        }

                                to2++;

                                if (to < n && to2 < m && n < m) {
                                        to++;
                                }

                                if (to < n && n >= m) {
                                        to++;
                                }

                                if (to2 > m) {
                                        from++;
                                }

                                if (from > to) {
                                        dowhile= false;
                                }

                        }

                };

                // straight effect
                var straight = function (el) {
                        var counter = 0,
                                i,
                                j;

                        for (i = 1; i <= params[el.id].sph; i++) {
                                for (j = 1; j <= params[el.id].spw; j++) {
                                        order[el.id][counter] = i + '' + j;
                                        counter++;
                                }
                        }
                };

                var min = function (n,m) {
                        if (n > m) {
                                return m;
                        } else {
                                return n;
                        }
                };

                var max = function (n,m) {
                        if (n < m) {
                                return m;
                        } else {
                                return n;
                        }
                };

                var init = function (el) {

                        if( el.id === '' ){
                                el.id = uniqueIDPrefix + uniqueIDCounter++;
                        }

                        order[el.id]                = [];        // order of square appereance
                        images[el.id]                = [];
                        links[el.id]                = [];
                        linksTarget[el.id]        = [];
                        titles[el.id]                = [];
                        imagePos[el.id]                = 0;
                        squarePos[el.id]        = 0;
                        reverse[el.id]                = 1;

                        params[el.id] = $.extend({}, $.fn.coinslider.defaults, options);

                        // create images, links and titles arrays
                        $.each($('#' + el.id + ' img'), function (i, item) {
                                images[el.id][i]                = $(item).attr('src');
                                links[el.id][i]                        = $(item).parent().is('a') ? $(item).parent().attr('href') : '';
                                linksTarget[el.id][i]        = $(item).parent().is('a') ? $(item).parent().attr('target') : '';
                                titles[el.id][i]                = $(item).next().is('span') ? $(item).next().html() : '';
                                $(item).hide();
                                $(item).next().hide();
                        });

                        // set panel
                        $(el).css({
                                'background-image': 'url(' + images[el.id][0] + ')',
                                'width': params[el.id].width,
                                'height': params[el.id].height,
                                'position': 'relative',
                                'background-position': 'top left'
                        }).wrap("<div class='coin-slider' id='coin-slider-" + el.id + "' />");

                        // create title bar
                        $('#' + el.id).append("<div class='cs-title' id='cs-title-" + el.id + "' style='position: absolute; bottom:0; left: 0; z-index: 1000;'></div>");

                        setFields(el);

                        if(params[el.id].navigation){
                                setNavigation(el);
                        }

                        transition(el,0);
                        transitionCall(el);

                };

                this.each (
                        function () {
                                init(this);
                        }
                );
        };

        // default values
        $.fn.coinslider.defaults = {
                width: 565, // width of slider panel
                height: 290, // height of slider panel
                spw: 7, // squares per width
                sph: 5, // squares per height
                delay: 3000, // delay between images in ms
                sDelay: 30, // delay beetwen squares in ms
                opacity: 0.7, // opacity of title and navigation
                titleSpeed: 500, // speed of title appereance in ms
                effect: '', // random, swirl, rain, straight
                links : true, // show images as links
                hoverPause: true, // pause on hover
                prevText: 'prev',
                nextText: 'next',
                navigation: true, // show/hide prev, next and buttons
                showNavigationPrevNext: true,
                showNavigationButtons: true,
                navigationPrevNextAlwaysShown: false
        };

})(jQuery);
